package net.seratch.taskun.scheduler.util;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import net.seratch.taskun.scheduler.config.SchedulerConfig;
import net.seratch.taskun.util.CalendarUtil;

import org.apache.commons.lang.StringUtils;

/**
 * Scheduler utility
 * 
 * @author Kazuhiro Sera
 */
public final class SchedulerUtil {

	/**
	 * Is working at the specified server or not
	 * 
	 * @param config
	 *            scheduler config
	 * @param name
	 *            server name
	 * @return result
	 */
	public static boolean isWorkingOnNamedServerHost(SchedulerConfig config,
			String name) {
		String expected = config.getNamedServerHostname(name);
		if (StringUtils.isEmpty(expected)) {
			return false;
		}
		try {
			return getHostname().matches(expected);
		} catch (UnknownHostException e) {
			return false;
		}
	}

	/**
	 * Get server name if exist
	 * 
	 * @param config
	 *            scheduler config
	 * @param hostname
	 *            server hostname
	 * @return result
	 */
	public static String getWorkingServerName(SchedulerConfig config,
			String hostname) {
		Map<String, String> servers = config.namedServers;
		Set<String> names = servers.keySet();
		for (String name : names) {
			if (hostname.matches(servers.get(name))) {
				return name;
			}
		}
		return hostname;
	}

	public static String getHostname() throws UnknownHostException {
		return InetAddress.getLocalHost().getCanonicalHostName();
	}

	/**
	 * get delay value
	 * 
	 * @param executeDate
	 *            the time to execute
	 * @param timeUnit
	 *            time unit
	 * @return delay value in the time unit
	 */
	public static long getDelayValue(Calendar executeDate, TimeUnit timeUnit) {
		Calendar current = CalendarUtil.getCurrentTime();
		long delayMillisecs = executeDate.getTimeInMillis()
				- current.getTimeInMillis();
		if (timeUnit.equals(TimeUnit.DAYS)) {
			return delayMillisecs / 1000 / 60 / 60 / 24;
		} else if (timeUnit.equals(TimeUnit.HOURS)) {
			return delayMillisecs / 1000 / 60 / 60;
		} else if (timeUnit.equals(TimeUnit.MICROSECONDS)) {
			return delayMillisecs * 1000;
		} else if (timeUnit.equals(TimeUnit.MILLISECONDS)) {
			return delayMillisecs;
		} else if (timeUnit.equals(TimeUnit.MINUTES)) {
			return delayMillisecs / 1000 / 60;
		} else if (timeUnit.equals(TimeUnit.NANOSECONDS)) {
			return delayMillisecs * 1000 * 1000;
		} else if (timeUnit.equals(TimeUnit.SECONDS)) {
			return delayMillisecs / 1000;
		} else {
			throw new UnsupportedOperationException("unexpected TimeUnit value");
		}
	}

}
